using AOT;
using SocketWeaver.FixedMath;
using System;
using System.Runtime.InteropServices;

namespace SocketWeaver.FPhysics2D
{
    public static class FPhysicsConstants
    {
        public const int SHAPE_OVERLAP_COLLIDER_COUNT_2D = 64;
        public const int SHAPE_OVERLAP_BODY_COUNT_3D = 128;

        public const int MAX_CONTACT_COUNT_2D = 1024 * 5 * 2;
        public const int MAX_CONTACT_COUNT_3D = 1024 * 5 * 20;

        public const int MAX_BODY_COLLISION_COUNT_2D = 32;
        public const int MAX_BODY_COLLISION_COUNT_3D = 64;

        public static FFloat SMALLEST_RAYCAST_RANGE = FFloat.FromDivision(1, 1000);
    }

    public enum LogLevel
    {
        Verbose = 0,
        Warning = 1,
        Error = 2
    }

    public enum BodyType
    {
        Static = 0,
        Kinematic = 1,
        Dynamic = 2
    }


    public enum ContactState
    {
        Default = 0,
        Enter = 1,
        Exit = 2,
        Inactive = 3,
        Active = 4,
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ContactExport2D
    {
        public UInt32 id;
        public int count;

        public UInt32 k1;
        public FFloat n1;
        public FFloat t1;

        public UInt32 k2;
        public FFloat n2;
        public FFloat t2;

        public FVector2 relativeVelocity;
        public bool isTrigger;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ColliderId2D
    {
        public UInt16 bodyId;
        public byte fixtureId;
    }

    public struct Collision2DCache
    {
        public ColliderId2D collider1;
        public ColliderId2D collider2;
    }

    internal delegate void debugCallback(string message);

    internal delegate void ContactEnterCallBack2D(IntPtr contactPtr, UInt64 contactID);
    internal delegate void ContactExitCallBack2D(IntPtr contactPtr, UInt64 contactID);
    internal delegate void RollbackAddRigidbodyCallback2D(UInt32 externalID, UInt16 bodyID, IntPtr previousBody, IntPtr world);
    internal delegate void RollbackRemoveRigidbodyCallback2D(UInt32 externalID, UInt16 bodyID, IntPtr body, IntPtr world);

    internal delegate void ContactEnterCallBack3D(IntPtr contactPtr, UInt64 contactID);
    internal delegate void ContactExitCallBack3D(IntPtr contactPtr, UInt64 contactID);
    internal delegate void RollbackAddRigidbodyCallback3D(UInt32 externalID, UInt16 bodyID, IntPtr previousBody, IntPtr world);
    internal delegate void RollbackRemoveRigidbodyCallback3D(UInt32 externalID, UInt16 bodyID, IntPtr body, IntPtr world);

    public static class NativeParallelEventHandler
    {
        public static LogLevel logLevel = LogLevel.Verbose;

        [MonoPInvokeCallback(typeof(debugCallback))]
        public static void OnDebugCallback(string message)
        {
            //if (logLevel > 0)
            //{
            //    return;
            //}
            UnityEngine.Debug.LogWarning(message);
        }
    }
}
